//package ar.edu.itba.pod.legajo47573;
//
//import java.io.BufferedReader;
//import java.io.IOException;
//import java.io.InputStreamReader;
//import java.rmi.AlreadyBoundException;
//import java.rmi.NotBoundException;
//import java.rmi.RemoteException;
//import java.rmi.registry.LocateRegistry;
//import java.rmi.registry.Registry;
//import java.util.List;
//import java.util.Set;
//
//import org.joda.time.Duration;
//
//import ar.edu.itba.balance.api.AgentsBalancer;
//import ar.edu.itba.balance.api.AgentsTransfer;
//import ar.edu.itba.balance.api.NodeAgent;
//import ar.edu.itba.event.RemoteEventDispatcher;
//import ar.edu.itba.node.Node;
//import ar.edu.itba.node.NodeInformation;
//import ar.edu.itba.node.api.ClusterAdministration;
//import ar.edu.itba.node.api.NodeStatistics;
//import ar.edu.itba.node.api.StatisticReports;
//import ar.edu.itba.pod.agent.market.Resource;
//import ar.edu.itba.pod.agent.market.ResourceAgent;
//import ar.edu.itba.pod.agent.runner.Agent;
//import ar.edu.itba.pod.agent.runner.Simulation;
//import ar.edu.itba.pod.legajo44228.administration.DistributedClusterAdministration;
//import ar.edu.itba.pod.legajo44228.agents.AgentsFactory;
//import ar.edu.itba.pod.legajo44228.balance.AgentsBalancerImpl;
//import ar.edu.itba.pod.legajo44228.balance.DistributedAgentsTransfer;
//import ar.edu.itba.pod.legajo44228.event.LocalEventDispatcher;
//import ar.edu.itba.pod.legajo44228.simulation.DistributedSimulationNode;
//import ar.edu.itba.pod.legajo44228.statistics.StatisticReportsImpl;
//import ar.edu.itba.pod.multithread.EventDispatcher;
//import ar.edu.itba.pod.time.TimeMapper;
//import ar.edu.itba.pod.time.TimeMappers;
//
//public class RunSimulation {
//
//	private static NodeInformation info = null;
//	private static RemoteEventDispatcher remoteDispatcher = null;
//	private static EventDispatcher localDispatcher = null;
//	private static ClusterAdministration cluster = null;
//	private static AgentsTransfer agents = null;
//	private static AgentsBalancer balancer = null;
//	private static Simulation simulation = null;
//
//	private static TimeMapper timeMapper = TimeMappers.oneSecondEach(Duration.standardHours(6));
//
//	static Resource gold = new Resource("Mineral", "Gold");
//	static Resource copper = new Resource("Mineral", "Copper");
//	static Resource steel = new Resource("Alloy", "Steel");
//
//
//	public static void main(String[] args) {
//
//		int auxPort = Integer.parseInt(args[1]);
//		String id = args[0] + ":" + args[1];
//		info = new NodeInformation(args[0], auxPort, id);
//		
//		TimeMapper timeMapper = TimeMappers.oneSecondEach(Duration.standardHours(10));
//		
//		final MyNode node = new MyNode(info, timeMapper);
//		Thread thread = new Thread(node);
//		thread.start();
//
//		try {
//
//			cluster = node.getCluster();
//			localDispatcher = node.getDispatcher();
//			remoteDispatcher = node.getRemoteDispatcher();
//
//			simulation = node.getSimulation();
//			StatisticReports estadisticas = node.getStatistics();
//
//			agents = node.getTransfer();
//			balancer = node.getBalancer();
//
//		} catch (RemoteException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} catch (AlreadyBoundException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//
//		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//
//		while(true) {
//
//			try {
//				String[] line = br.readLine().split (" ");
//				if ("connect".equals(line[0])) {
//					cluster.connectToGroup(line[1], Integer.parseInt(line[2]));
//				} else if ("disconnect".equals(line[0])) {
//					disconnect();
//				} else if ("create".equals(line[0])) {
//					cluster.createGroup();
//				} else if ("info".equals(line[0])) {
//					showClusterInfo();
//				} else if ("estadisticas".equals(line[0])) {
//					showStatistics();
//				} else if ("show".equals(line[0])) {
//					showAgents(simulation);
//				} else if ("start".equals(line[0])){
//					simulation.start(new Duration(10000000));
//				} else if ("add".equals(line[0])) {
//					addAgent(line[1], line[2], line[3]);
////				} else if ("balance".equals(line[0])){
////					balancer.doFullBalance();
////				} else if ("election".equals(line[0])) {
////					balancer.bullyElection(node, System.currentTimeMillis());
//				} else if ("exit".equals(line[0])) {
//					return;
//				} else {
//					System.out.println("La entrada no es valida.");
//				}
//			} catch (IOException exp) {
//				System.out.println("La entrada no es valida --> IOException. " + exp.getMessage());
//			} catch (NumberFormatException exp) {
//				System.out.println("La entrada no es valida --> NumberFormatException.");
//			} catch (NotBoundException exp) {
//				System.out.println("No se encuentra la clase remota.");
//			} catch (Exception exp){
//				System.out.println("Se produjo una excepcion." + exp.getMessage());
//			}
//		}
//	}
//
//	private static void showClusterInfo() throws RemoteException {
//
//		System.out.println("Node: " + info.id() + "@" + info.host() + ":" + info.port());
//		if (!cluster.isConnectedToGroup()) {
//			System.out.println("The node is not connected to a group.");
//			return;
//		}
//		System.out.println("This node belongs to the cluster: " + cluster.getGroupId());
//		Set<NodeInformation> nodes = cluster.connectedNodes();
//		System.out.println("Connected nodes:");
//		for (NodeInformation aux : nodes) {
//			System.out.println(aux.host() + ":" + aux.port());
//		}
//	}
//
//	private static void showAgents(Simulation simulation) {
//
//		List<Agent> agents = simulation.getAgentsRunning();
//		for (Agent agent : agents) {
//			System.out.println(agent.name());
//		}
//	}
//
//	private static void showStatistics() {
//
//		try {
//			System.out.println("-------------------------------------------------");
//			System.out.println("Estadisticas del cluster: " + cluster.getGroupId());
//			System.out.println("-------------------------------------------------");
//			Set<NodeInformation> list = cluster.connectedNodes();
//			for (NodeInformation node : list) {
//				try {
//					Registry registry = LocateRegistry.getRegistry(node.host(), node.port());
//					StatisticReports remoteStub = (StatisticReports) registry.lookup(Node.STATISTIC_REPORTS);
//					NodeStatistics statistics = remoteStub.getNodeStatistics();
//					System.out.println("Node: "+ node.id() + " --> Agents: " + statistics.getNumberOfAgents());
//				} catch (Exception e) {
//					System.out.println("No se pueden obtener estadisticas del nodo " + node.id());
//				}
//			}
//		} catch (RemoteException e1) {
//			// No deberia pasar. Se ejecuta localmente.
//		}
//	}
//
//	public static void disconnect() {
//
//		try {
//			int cant = agents.getNumberOfAgents();
//			List<NodeAgent> myAgents = agents.stopAndGet(cant);
//			balancer.shutdown(myAgents);
//			cluster.disconnectFromGroup(info);
//		} catch (Exception e) {
//			System.out.println("Se produjo un error al desconectar el nodo. Mensaje: " + e.getMessage());
//		}
//	}
//
//	private static void addAgent(String resource, String type, String cantidad) throws IOException {
//
//		int cant = Integer.valueOf(cantidad);
//		try {
//			for (int i = 0; i < cant; i++) {
//				ResourceAgent aux = AgentsFactory.getAgent(info, type, resource);
//				((AgentsBalancerImpl)balancer).addAgentLocal(new NodeAgent(info, aux));
//			}
//		} catch (Exception e) {
//			System.out.println("Se produjo un error agregar el agente. Mensaje: " + e.getMessage());
//		}
//	}
//	
//	private static 
//}